home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
nn.zip
/
SAVE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-31
|
16KB
|
699 lines
#include <signal.h>
#include <errno.h>
#include "config.h"
#include "term.h"
#include "keymap.h"
#include "news.h"
/*
* save (or print) articles
*/
/* #define PAGED_OUTPUT /* does not work yet!! */
export char *default_save_file = "+$F";
export char *unshar_header_file = "Unshar.Headers";
export int use_mail_folders = 0;
export int use_mmdf_folders = 0;
export int save_report = 1;
export int quick_save = 0;
export int conf_append = 0;
export int conf_create = 1;
export char *save_counter_format = "%d"; /* format of save counter */
export char printer[FILENAME] = PRINTER; /* lp -s -ol */
export char *patch_command = "patch";
export char *unshar_command = SHELL;
extern int file_completion();
import char *temp_file;
import int shell_restrictions;
static int save_mode;
static char *unshar_cmd;
#define HEADER_HANDLING 0x0f /* what should we do with the header */
#define NO_HEADER 0 /* save without a header */
#define FULL_HEADER 1 /* save with full header */
#define SHORT_HEADER 2 /* save with partial header */
#define SHORT_HEADER_DG 3 /* save with partial header (digest) */
#define SEPARATE_FILES 0x0100 /* save as separate files */
#define UNIQUE_FILES 0x0200 /* save in unique files */
#define FILE_IS_NEW 0x0400 /* this is a new file */
#define APPEND_ARTNUM 0x0800 /* append article number to file name */
#define IS_PIPE 0x1000 /* output is on pipe */
#define DO_UNSHAR 0x2000 /* unshar article (or patch) */
#define DO_PATCH 0x4000 /* patch article */
#define DO_DECODE 0x8000 /* uudecode article */
/* open modes for open_news_article for the various HEADER_HANDLINGs */
static int open_mode[] = {
SKIP_HEADER,
0,
FILL_NEWS_HEADER | SKIP_HEADER,
FILL_DIGEST_HEADER | SKIP_HEADER
};
static FILE *save_file; /* output stream for saved files */
static char *save_name; /* save file name */
#ifdef PAGED_OUTPUT
static FILE *pager_stream = NULL; /* unshar/patch output stream */
static char pager_redir[40];
#endif
static int counter_index; /* index into save_name of '*' */
static int uniq_counter; /* separate files counter */
static char last_dir[FILENAME] = "";
char *init_save(command, mode_textp)
char command;
char **mode_textp;
{
char *mode_text;
static char last_input[FILENAME] = "";
static char name_buf[512]; /* buffer for file name & command expansion */
char *start, *last, *np;
char *ckdir_path();
uniq_counter = 0;
switch (command) {
case K_SAVE_FULL_HEADER:
save_mode = FULL_HEADER;
mode_text = "Save";
goto cont_save;
case K_SAVE_SHORT_HEADER:
save_mode = SHORT_HEADER;
mode_text = "Output";
goto cont_save;
case K_SAVE_NO_HEADER:
save_mode = NO_HEADER;
mode_text = "Write";
cont_save:
if (quick_save && (current_group->group_flag & G_FOLDER) == 0) {
if (current_group->save_file)
save_name = current_group->save_file;
else
save_name = default_save_file;
strcpy(last_input, save_name);
save_name = last_input;
} else {
prompt("\1%s on\1 (+~|) ", mode_text);
save_name = get_s(last_input, current_group->save_file, NONE,
file_completion);
if (save_name == NULL || *save_name == NUL) return NULL;
if (save_name[1] == NUL && save_name[0] == '+')
save_name = default_save_file;
else
if (current_group->save_file == NULL ||
strcmp(save_name, current_group->save_file))
strcpy(last_input, save_name);
}
if (*save_name == '|') {
if (shell_restrictions) {
msg("Restricted operation - pipes not allowed");
return NULL;
}
mode_text = "Pipe";
save_name++;
save_mode |= IS_PIPE;
if (*save_name == '|' || *save_name == '*') {
save_mode |= SEPARATE_FILES;
save_name++;
}
} else {
counter_index = strlen(save_name) - 1;
np = save_name + counter_index;
if (*np == '*')
save_mode |= SEPARATE_FILES | UNIQUE_FILES;
else
if (counter_index > 0 && strcmp(--np, "$N") == 0) {
if (current_group->group_flag & G_FOLDER) {
msg("$N is not defined in a folder");
return NULL;
}
counter_index--;
strcpy(np, "*");
save_mode |= SEPARATE_FILES | APPEND_ARTNUM;
}
}
break;
case K_UUDECODE:
save_mode = NO_HEADER | DO_UNSHAR | DO_DECODE;
mode_text = "Decode";
goto patch1;
case K_PATCH:
save_mode = NO_HEADER | SEPARATE_FILES | DO_UNSHAR | DO_PATCH;
mode_text = "Patch";
unshar_cmd = patch_command;
goto patch1;
case K_UNSHAR:
save_mode = NO_HEADER | SEPARATE_FILES | DO_UNSHAR;
mode_text = "Unshar";
unshar_cmd = unshar_command;
patch1:
prompt("\1%s Directory:\1 ", mode_text);
save_name = get_s(last_dir, current_group->save_file, NONE, file_completion);
if (save_name == NULL || *save_name == NUL) return NULL;
strcpy(last_dir, save_name);
break;
case K_PRINT:
save_mode = SHORT_HEADER | IS_PIPE;
if (shell_restrictions) {
save_name = printer;
} else {
prompt("\1Print command:\1 ");
save_name = get_s(NONE, printer, NONE, NO_COMPLETION);
if (save_name == NULL || *save_name == NUL) return NULL;
strcpy(printer, save_name);
}
mode_text = "Print";
break;
default:
msg("Illegal save command: %d", command);
return NULL;
}
if (save_name) {
if (save_mode & IS_PIPE || *save_name == '+' || *save_name == '~') {
if (!expand_file_name(name_buf, save_name))
return NULL;
if (save_mode & SEPARATE_FILES)
counter_index = strlen(name_buf) - 1;
} else
strcpy(name_buf, save_name);
save_name = name_buf;
if (!(save_mode & IS_PIPE)) {
if (file_exist(save_name, (save_mode & DO_UNSHAR) ? "wd" : "wf")) {
if (save_mode & DO_UNSHAR) {
int len = strlen(save_name);
if (save_name[len - 1] != '/')
strcpy(save_name + len, "/");
} else
if (conf_append) {
printf("\rAppend to: %s ? ", save_name);
clrline();
if (!yes(0)) return NULL;
}
} else {
if (errno != ENOENT) {
msg("Cannot access %s", save_name);
return NULL;
}
if (save_mode & DO_UNSHAR) {
int len = strlen(save_name);
if (save_name[len - 1] != '/')
strcpy(save_name + len, "/");
}
start = ckdir_path(save_name);
if (start == NULL) {
msg("No permission");
return NULL;
}
last = strrchr(start, '/');
/* last != NULL => non-existing directories */
if (conf_create && (!(save_mode & SEPARATE_FILES) || last)) {
printf("\rCreate ");
for (np = save_name; *np; np++) {
if (np == start) putchar('\"');
putchar(*np);
if ((save_mode & SEPARATE_FILES) && np == last) break;
}
printf("\" ?");
clrline();
if (yes(last != NULL) <= 0) return NULL;
}
if (last && !mkdirs_in_path(save_name, start))
return NULL;
}
}
}
if (mode_textp) *mode_textp = mode_text;
save_mode |= FILE_IS_NEW; /* so save() will open it */
if (save_mode & DO_DECODE) {
uud_start(save_name);
save_mode &= ~DO_UNSHAR;
}
#ifdef PAGED_OUTPUT
if (save_mode & DO_UNSHAR) {
int was_raw = unset_raw();
pager_stream = popen(pager, "w");
if (was_raw) raw();
if (pager_stream == NULL) {
pager_redir[0] = NUL;
msg("Warning: Pager '%s' not found");
} else
sprintf(pager_redir, " 1>&%d 2>&1 ; ", fileno(pager_stream));
system("fdcheck");
}
#endif
return save_name;
}
save(ah)
article_header *ah;
{
register FILE *art;
register c, lcount, mode;
news_header_buffer hdrbuf;
int was_raw = 0;
char copybuf[1024];
if (ah->a_group) init_group(ah->a_group);
mode = save_mode & HEADER_HANDLING;
if (mode == SHORT_HEADER && ah->flag & A_DIGEST)
mode = SHORT_HEADER_DG;
art = open_news_article(ah, open_mode[mode], hdrbuf, (char *)NULL);
if (art == NULL) {
msg("Cannot read %s", group_path_name);
return 0;
}
if (save_mode & DO_DECODE) {
save_file = NULL;
c = uudecode(ah, art);
fclose(art);
return (c < 0) ? 0 : 1;
}
if (save_mode & UNIQUE_FILES) {
do {
uniq_counter++;
sprintf(copybuf, save_counter_format, uniq_counter);
if (strcmp(save_name + counter_index, copybuf) == 0) {
msg("save-counter \"%s\" does not generate unique file names",
save_counter_format);
goto fatal;
}
strcpy(save_name + counter_index, copybuf);
} while (file_exist(save_name, (char *)NULL));
save_mode |= FILE_IS_NEW;
} else
if (save_mode & APPEND_ARTNUM)
sprintf(save_name + counter_index, "%d", ah->a_number);
if (save_mode & FILE_IS_NEW) {
if (save_mode & (IS_PIPE | DO_UNSHAR))
was_raw = unset_raw();
if (save_mode & IS_PIPE) {
if ((save_file = popen(save_name, "w")) == NULL) {
msg("Cannot pipe to %s", save_name);
goto fatal;
}
} else
if (save_mode & DO_UNSHAR) {
if ((save_mode & DO_PATCH) == 0) {
if (!unshar_position(art))
goto fatal;
if (unshar_header_file)
store_header(ah, art, save_name, unshar_header_file);
}
if (save_name)
#ifdef PAGED_OUTPUT
sprintf(copybuf, "cd %s && %s %s", save_name, unshar_cmd, pager_redir);
else
sprintf(copybuf, "%s %s", unshar_cmd, pager_redir);
#else
new_temp_file();
sprintf(copybuf,
"cd %s && { %s 2>&1 ; } | tee %s ; cat %s >> %s.Result ; rm %s",
save_name != NULL ? save_name : ".", unshar_cmd,
temp_file, temp_file,
(save_mode & DO_PATCH) ? "Patch" : "Unshar",
temp_file);
#endif
save_file = popen(copybuf, "w");
if (save_file == NULL) {
msg("Cannot exec: '%s'", copybuf);
goto fatal;
}
#ifdef PAGED_OUTPUT
fprintf(pager_stream, "\r\n%s %s\r\n",
save_mode & DO_PATCH ? "PATCHING FROM" : "UNPACKING",
ah->subject ? ah->subject : "ARTICLE");
fflush(pager_stream);
#else
printf("\r\n%s %s\r\n",
save_mode & DO_PATCH ? "PATCHING FROM" : "UNPACKING",
ah->subject ? ah->subject : "ARTICLE"); fl;
#endif
} else {
if ((save_file = open_file(save_name, OPEN_APPEND)) == NULL) {
msg("Cannot write %s", save_name);
fclose(art);
return 0;
}
if (ftell(save_file) != (off_t)0)
save_mode &= ~FILE_IS_NEW;
}
}
clrline();
s_pipe = 0;
if (mode != NO_HEADER)
mailbox_format(save_file, 1);
if (mode == FULL_HEADER) {
off_t cnt = ah->fpos - ah->hpos;
while (--cnt >= 0) {
if ((c = getc(art)) == EOF) break;
putc(c, save_file);
}
} else
if (mode == SHORT_HEADER) {
if (news.ng_from)
fprintf(save_file, "From: %s\n", news.ng_from);
if (news.ng_date)
fprintf(save_file, "Date: %s\n", news.ng_date);
if (news.ng_subj)
fprintf(save_file, "Subject: %s\n", news.ng_subj);
fputc(NL, save_file);
} else
if (mode == SHORT_HEADER_DG) {
if (digest.dg_from)
fprintf(save_file, "From: %s\n", digest.dg_from);
if (digest.dg_date)
fprintf(save_file, "Date: %s\n", digest.dg_date);
if (digest.dg_subj)
fprintf(save_file, "Subject: %s\n", digest.dg_subj);
fputc(NL, save_file);
}
fflush(save_file);
if (s_pipe) goto broken_pipe;
mode = mode != NO_HEADER && (save_mode & (IS_PIPE | DO_UNSHAR)) == 0;
lcount = 0;
while (ftell(art) < ah->lpos && fgets(copybuf, 512, art)) {
lcount++;
if (mode && is_header_line(copybuf))
fputc('~', save_file);
fputs(copybuf, save_file);
if (s_pipe) goto broken_pipe;
}
if (mode != NO_HEADER)
lcount += mailbox_format(save_file, 0);
broken_pipe:
fclose(art);
if (save_mode & DO_UNSHAR) {
pclose(save_file);
save_file = NULL;
} else {
if (s_pipe)
msg("Command did not read complete article!");
else
if (save_report)
msg((save_mode & IS_PIPE) ? "%s: %d lines piped" :
(save_mode & FILE_IS_NEW) ? "%s created: %d lines written" :
"%s: %d lines appended", save_name, lcount);
if (s_pipe || (save_mode & SEPARATE_FILES))
end_save();
else
save_mode &= ~FILE_IS_NEW;
}
#ifdef MAIL_READING
if (mail_auto_delete && (save_mode & IS_PIPE) == 0)
if (current_group->group_flag & G_MAILBOX)
if ((ah->flag & A_CANCEL) == 0)
fcancel(ah);
#endif
if (was_raw) raw();
ah->flag |= A_ST_FILED;
return !s_pipe || (save_mode & SEPARATE_FILES);
fatal:
if (was_raw) raw();
fclose(art);
return 0;
}
end_save()
{
if (save_file) {
if (save_mode & (IS_PIPE | DO_UNSHAR))
pclose(save_file);
else
fclose(save_file);
save_file = NULL;
}
if (save_mode & DO_DECODE) {
uud_end();
}
#ifdef PAGED_OUTPUT
if (pager_stream != NULL) {
pclose(pager_stream);
pager_stream = NULL;
}
#else
if (save_mode & DO_UNSHAR) {
import char *delayed_msg;
delayed_msg = (save_mode & DO_PATCH) ?
"Output is saved in Patch.Result" :
"Output is saved in Unshar.Result";
}
#endif
}
store_header(ah, f, dir, file)
article_header *ah;
FILE *f;
char *dir, *file;
{
register int c;
off_t endpos;
FILE *h;
if (dir != (char *)NULL && file[0] != '/')
file = relative(dir, file);
if ((h = open_file(file, OPEN_APPEND)) == NULL) {
msg("Cannot open %s", file);
return;
}
fseek(h, (off_t)0, 2);
if (!use_mmdf_folders && ftell(h) > 0) putc(NL, h); /* just in case */
mailbox_format(h, 1);
endpos = ftell(f) - ah->hpos;
fseek(f, ah->hpos, 0);
while (--endpos >= 0 && (c = getc(f)) != EOF)
putc(c, h);
mailbox_format(h, 0);
fclose(h);
}
mailbox_format(f, top)
FILE *f;
int top;
{
time_t now;
char *ctime();
if (use_mmdf_folders) {
fprintf(f, "\001\001\001\001\n");
return 0;
}
if (top == 0) {
fputc(NL, f);
return 1;
}
if (use_mail_folders) {
time(&now);
fprintf(f, "From %s %s",
current_group->group_name, ctime(&now));
return 1;
}
return 0;
}
char *run_mkdir(dir, name_buf)
char *dir, *name_buf;
{
if (dir == NULL) {
prompt("\1Directory: \1");
dir = get_s(last_dir, NONE, NONE, file_completion);
if (dir == NULL || *dir == NUL) return NULL;
strcpy(last_dir, dir);
}
if (*dir == '+' || *dir == '~') {
if (!expand_file_name(name_buf, dir))
return NULL;
dir = name_buf;
}
if (file_exist(dir, (char *)NULL)) {
msg("Directory %s already exists", dir);
return NULL;
}
if (mkdir(dir, 0755)) {
msg("Cannot make %s", dir);
return NULL;
}
return dir;
}
change_dir(dir, in_init)
char *dir;
int in_init;
{
char dir_buf[FILENAME];
if (dir == NULL) {
prompt("\1Directory: \1");
dir = get_s(last_dir, NONE, NONE, file_completion);
}
if (dir == NULL || *dir == NUL) return 0;
strcpy(last_dir, dir);
if (*dir == '+' || *dir == '~') {
if (!expand_file_name(dir_buf, dir)) return in_init;
dir = dir_buf;
}
if (chdir(dir) == 0) {
if (!in_init) msg("Directory: %s", dir);
return 0;
}
if (in_init) return 1;
if (errno == EACCES)
msg("Cannot access directory %s", dir);
else {
/* should ask and create directory here */
msg("Directory not found: %s", dir);
}
return 0;
}
/*
* return pointer to first path name component, that does not exist
*/
static char *ckdir_path(name)
char *name;
{
char *slash;
char *component;
component = name;
while (slash = strchr(component, '/')) {
if (slash == component) {
/* ...//... */
component++;
continue;
}
*slash = NUL;
if (file_exist(name, "drx")) {
*slash++ = '/';
component = slash;
continue;
}
if (file_exist(name, (char *)NULL)) {
*slash = '/';
return NULL;
}
*slash = '/';
break;
}
return component;
}
/*
* create directories in path name, starting from start
*/
static mkdirs_in_path(name, start)
char *name, *start;
{
char *slash;
char *component;
component = start;
while (slash = strchr(component, '/')) {
if (slash == component) {
/* ...//... */
component++;
continue;
}
*slash = NUL;
if (mkdir(name, 0755)) {
msg("Cannot make %s/", name);
*slash = '/';
return 0;
}
*slash++ = '/';
component = slash;
}
return 1;
}